package cn.kgc.controller;

import cn.kgc.base.vo.OrderItemVo;
import cn.kgc.base.vo.UmsMemberReceiveAddressVo;
import cn.kgc.client.CartFeignClient;
import cn.kgc.client.UmsFeignClient;
import cn.kgc.commons.exception.HttpException;
import cn.kgc.commons.util.RedisUtil;
import cn.kgc.commons.util.UserContextHolder;
import cn.kgc.commons.vo.Result;
import cn.kgc.constant.OrderConstant;
import cn.kgc.service.OrderService;
import cn.kgc.vo.OrderConfirmVo;
import cn.kgc.vo.OrderSubmitVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.User;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: 石浩杰
 * @date: 2023-01-02 09:42
 */
@RestController
@RequestMapping("/order")
@Api(tags = "订单接口")
public class OmsOrderController {

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Resource
    private CartFeignClient cartFeignClient;

    @Resource
    private UmsFeignClient umsFeignClient;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private OrderService orderService;

    //1 获得订单的相关信息(多个收货地址(用户模块获得) 购物车中选中的商品(购物车服务中获得) 应付金额 总金额)
    @GetMapping("/getOrderConfirm")
    @ApiOperation(value = "获得订单的相关信息",httpMethod = "GET",
            produces = "application/json;charset=utf-8",response = Result.class)
    @CrossOrigin
    public OrderConfirmVo getOrderConfirm(){
        //登录的用户的ID
        long userId= Long.parseLong(UserContextHolder.getInstance().getUserId());
        OrderConfirmVo orderConfirmVo=new OrderConfirmVo();
        //获得登录用户的收货地址(远程接口)
        CompletableFuture<Void> future1=CompletableFuture.runAsync(()->{
            Result<List<UmsMemberReceiveAddressVo>> result=umsFeignClient.getUmsMemberReceiveAddress(userId);
            if (result.getData()!=null){ //如果服务没有降级，保存所有的收货地址
                orderConfirmVo.setAddressVoList(result.getData());
            }
        },threadPoolExecutor);
        //获得登录用户购物车中选中的商品(远程接口)
        CompletableFuture<Void> future2=CompletableFuture.runAsync(()->{
            Result<List<OrderItemVo>> result=cartFeignClient.getOrderItemVo(userId);
            if (result.getData()!=null){ //如果服务没有降级，保存所有的收货地址
                orderConfirmVo.setCartItemVoList(result.getData());
                //商品总价
                BigDecimal totalPrice=new BigDecimal(0);
                List<OrderItemVo> orderItemVoList=orderConfirmVo.getCartItemVoList();
                for (OrderItemVo orderItemVo : orderItemVoList) {
                    totalPrice=totalPrice.add(orderItemVo.getTotalPrice());
                }
                orderConfirmVo.setPayTotalPrice(totalPrice);//应付金额
                orderConfirmVo.setTotalPrice(totalPrice);//总金额
            }
        },threadPoolExecutor);

        try {
            //异步任务执行完成以后，程序再向下执行
            CompletableFuture.allOf(future1,future2).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //生成令牌
        String token= UUID.randomUUID().toString().replaceAll("-","");
        //将令牌保存到redis中
        String orderTokenKey= OrderConstant.ORDER_TOKEN_PREFIX+token;
        redisUtil.set(orderTokenKey,token,OrderConstant.ORDER_TOKEN_TIME, TimeUnit.MINUTES);
        //返回令牌
        orderConfirmVo.setOrderToken(token);
        return orderConfirmVo;
    }
    //2 生成订单
    //幂等性
    //(1) 一些基本的sql语句本身就有幂等性
    //select 没有幂等性问题
    //insert 有幂等性问题,设置唯一索引
    //update 有幂等性问题,乐观锁
    //delete 没有幂等性问题
    @ApiOperation(value = "生成订单,返回订单编号",httpMethod = "POST",
            produces = "application/json;charset=utf-8",response = Result.class)
    @PostMapping("/createOrder")
    public Result<String> generateOrder(@RequestBody OrderSubmitVO orderSubmitVO){
        //保证接口幂等性
        String orderToken=orderSubmitVO.getOrderToken();
        String orderTokenKey=OrderConstant.ORDER_TOKEN_PREFIX+orderToken;
        //判断接口幂等性
        boolean flag=redisUtil.execute(orderTokenKey,orderToken);
        if (!flag){
            throw new HttpException(50001, HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
        long memberId=Long.parseLong(UserContextHolder.getInstance().getUserId());
        String memberName=UserContextHolder.getInstance().getUserName();
        //保存:订单的信息
        String orderSn=orderService.generateOrderInfo(orderSubmitVO,memberId,memberName);
        return Result.ok(orderSn,"http://mall-oms/otder/generateOrder");
        //保存:订单的商品信息

        //锁定库存
    }
}
